<script setup lang="ts">
import {
  NButton,
  NCard,
  NForm,
  NFormItem,
  NInput,
  NSelect,
  NPopconfirm,
  useMessage,
  useModal,
  NTag,
  NNumberAnimation,
  NSwitch,
  type DataTableColumns,
  type PaginationProps,
  type FormRules,
  type FormInst
} from 'naive-ui'
import { reactive, ref, h, computed } from 'vue'

import * as roleApi from '@/api/role'
import * as userApi from '@/api/user'
import { ScrollContainer, DynamicList } from '@/components'
import { useInjection } from '@/composables'
import { mediaQueryInjectionKey } from '@/injection'

import type { Role } from '@/api/role'
import type { User, UserQuery } from '@/api/user'

const { isMaxMd, isMaxLg } = useInjection(mediaQueryInjectionKey)

const message = useMessage()
const modal = useModal()

// 表格数据和分页
const dataList = ref<User[]>([])
const isRequestLoading = ref(false)
const checkedRowKeys = ref<Array<string>>([])

// 操作列折叠状态
const isActionsExpanded = ref(false)

// 分页配置
const pagination = reactive<PaginationProps>({
  page: 1,
  pageSize: 3,
  showSizePicker: true,
  pageSizes: [3, 6, 9, 12],
  itemCount: 0,
  showQuickJumper: true,
  onUpdatePage: (page: number) => {
    pagination.page = page
    getDataList()
  },
  onUpdatePageSize: (pageSize: number) => {
    pagination.pageSize = pageSize
    pagination.page = 1
    getDataList()
  },
})

// 搜索表单
const searchForm = reactive<UserQuery>({
  keyword: undefined,
  role: undefined,
  status: undefined,
})

// 新增/编辑表单
const formRef = ref<FormInst | null>(null)
const form = reactive<Omit<User, 'id' | 'createdAt' | 'updatedAt'>>({
  username: '',
  email: '',
  role: '',
  status: 'active',
})

const rules: FormRules = {
  username: {
    required: true,
    message: '请输入用户名',
  },
  email: {
    required: true,
    message: '请输入邮箱',
    type: 'email',
  },
  role: {
    required: true,
    message: '请选择角色',
  },
}

// 角色列表
const roleList = ref<Role[]>([])
const isLoadingRoles = ref(false)

// 统计数据
const userStats = reactive({
  total: 0,
  active: 0,
  inactive: 0,
})

// 获取角色列表
async function getRoleList() {
  isLoadingRoles.value = true
  try {
    const res = await roleApi.getRoles()
    roleList.value = res.list
  } catch {
    message.error('获取角色列表失败')
  } finally {
    isLoadingRoles.value = false
  }
}

// 获取用户列表
async function getDataList() {
  isRequestLoading.value = true
  try {
    const params: UserQuery = {
      page: pagination.page,
      pageSize: pagination.pageSize,
      keyword: searchForm.keyword,
      role: searchForm.role,
      status: searchForm.status,
    }
    const res = await userApi.getUsers(params)
    dataList.value = res.list || []
    pagination.itemCount = res.total || 0

    // 更新统计数据
    userStats.total = res.total || 0
    userStats.active = (res.list || []).filter((user) => user.status === 'active').length
    userStats.inactive = (res.list || []).filter((user) => user.status === 'inactive').length
  } catch (error) {
    console.error('=== Error getting users:', error)
    message.error('获取用户列表失败')
  } finally {
    isRequestLoading.value = false
  }
}

// 打开新增用户模态框
function openAddModal() {
  // 重置表单
  form.username = ''
  form.email = ''
  form.role = ''
  form.status = 'active'

  modal.create({
    autoFocus: false,
    title: '新增用户',
    preset: 'dialog',
    draggable: true,
    positiveText: '保存',
    negativeText: '取消',
    style: {
      width: '500px',
      ...(isMaxMd.value ? { marginInline: '16px' } : {}),
    },
    content: () => {
      return h('div', [
        h(
          NForm,
          {
            ref: (instance) => (formRef.value = instance as FormInst | null),
            model: form,
            rules: rules,
            labelPlacement: 'left',
            labelWidth: 80,
          },
          [
            h(NFormItem, { label: '用户名', path: 'username' }, [
              h(NInput, {
                value: form.username,
                'onUpdate:value': (value: string) => (form.username = value),
                clearable: true,
                placeholder: '请输入用户名',
              }),
            ]),
            h(NFormItem, { label: '邮箱', path: 'email' }, [
              h(NInput, {
                value: form.email,
                'onUpdate:value': (value: string) => (form.email = value),
                clearable: true,
                placeholder: '请输入邮箱',
              }),
            ]),
            h(NFormItem, { label: '角色', path: 'role' }, [
              h(NSelect, {
                value: form.role,
                'onUpdate:value': (value: string) => (form.role = value),
                options: roleList.value.map((role) => ({ label: role.name, value: role.id })),
                placeholder: '请选择角色',
                loading: isLoadingRoles.value,
                clearable: true,
              }),
            ]),
            h(NFormItem, { label: '状态' }, [
              h('div', { class: 'flex items-center' }, [
                h(NSwitch, {
                  value: form.status === 'active',
                  'onUpdate:value': (value: boolean) =>
                    (form.status = value ? 'active' : 'inactive'),
                }),
                h('span', { class: 'ml-2' }, form.status === 'active' ? '活跃' : '禁用'),
              ]),
            ]),
          ],
        ),
      ])
    },
    onPositiveClick: async () => {
      if (formRef.value) {
        const valid = await formRef.value.validate()
        if (valid) {
          // 新增用户
          try {
            await userApi.createUser(form)
            message.success('用户创建成功')
            getDataList()
            modal.destroyAll()
          } catch {
            message.error('用户创建失败')
          }
        }
      }
    },
    onNegativeClick: () => {
      modal.destroyAll()
    },
  })
}

// 打开编辑用户模态框
function openEditModal(user: User) {
  // 填充表单数据
  form.username = user.username
  form.email = user.email
  form.role = user.role
  form.status = user.status

  modal.create({
    autoFocus: false,
    title: '编辑用户',
    preset: 'dialog',
    draggable: true,
    positiveText: '保存',
    negativeText: '取消',
    style: {
      width: '500px',
      ...(isMaxMd.value ? { marginInline: '16px' } : {}),
    },
    content: () => {
      return h('div', [
        h(
          NForm,
          {
            ref: (instance) => (formRef.value = instance as FormInst | null),
            model: form,
            rules: rules,
            labelPlacement: 'left',
            labelWidth: 80,
          },
          [
            h(NFormItem, { label: '用户名', path: 'username' }, [
              h(NInput, {
                value: form.username,
                'onUpdate:value': (value: string) => (form.username = value),
                clearable: true,
                placeholder: '请输入用户名',
              }),
            ]),
            h(NFormItem, { label: '邮箱', path: 'email' }, [
              h(NInput, {
                value: form.email,
                'onUpdate:value': (value: string) => (form.email = value),
                clearable: true,
                placeholder: '请输入邮箱',
              }),
            ]),
            h(NFormItem, { label: '角色', path: 'role' }, [
              h(NSelect, {
                value: form.role,
                'onUpdate:value': (value: string) => (form.role = value),
                options: roleList.value.map((role) => ({ label: role.name, value: role.id })),
                placeholder: '请选择角色',
                loading: isLoadingRoles.value,
                clearable: true,
              }),
            ]),
            h(NFormItem, { label: '状态' }, [
              h('div', { class: 'flex items-center' }, [
                h(NSwitch, {
                  value: form.status === 'active',
                  'onUpdate:value': (value: boolean) =>
                    (form.status = value ? 'active' : 'inactive'),
                }),
                h('span', { class: 'ml-2' }, form.status === 'active' ? '活跃' : '禁用'),
              ]),
            ]),
          ],
        ),
      ])
    },
    onPositiveClick: async () => {
      if (formRef.value) {
        const valid = await formRef.value.validate()
        if (valid) {
          // 编辑用户
          try {
            await userApi.updateUser(user.id, form)
            message.success('用户更新成功')
            getDataList()
            modal.destroyAll()
          } catch {
            message.error('用户更新失败')
          }
        }
      }
    },
    onNegativeClick: () => {
      modal.destroyAll()
    },
  })
}

// 删除用户
async function deleteUserHandler(id: string) {
  try {
    await userApi.deleteUser(id)
    message.success('用户删除成功')
    getDataList()
  } catch {
    message.error('用户删除失败')
  }
}

// 批量删除用户
async function batchDeleteHandler() {
  if (checkedRowKeys.value.length === 0) {
    message.warning('请选择要删除的用户')
    return
  }

  try {
    await userApi.batchDeleteUsers(checkedRowKeys.value)
    message.success('批量删除成功')
    getDataList()
    checkedRowKeys.value = []
  } catch {
    message.error('批量删除失败')
  }
}

// 切换用户状态
async function toggleUserStatus(id: string, status: 'active' | 'inactive') {
  try {
    await userApi.updateUser(id, { status: status === 'active' ? 'inactive' : 'active' })
    message.success('用户状态更新成功')
    getDataList()
  } catch {
    message.error('用户状态更新失败')
  }
}

// 重置密码
function resetPasswordHandler(id: string) {
  const newPassword = ref<string>('')

  modal.create({
    autoFocus: false,
    title: '重置密码',
    preset: 'dialog',
    draggable: true,
    style: {
      width: '400px',
      ...(isMaxMd.value ? { marginInline: '16px' } : {}),
    },
    positiveText: '确定',
    negativeText: '取消',
    content: () => {
      return h('div', { class: 'p-4' }, [
        h(NFormItem, { label: '新密码' }, [
          h(NInput, {
            value: newPassword.value,
            'onUpdate:value': (value: string) => (newPassword.value = value),
            placeholder: '请输入新密码',
            type: 'password',
          }),
        ]),
      ])
    },
    onPositiveClick: async () => {
      if (!newPassword.value) {
        message.warning('请输入新密码')
        return
      }

      try {
        await userApi.resetPassword(id, newPassword.value)
        message.success('密码重置成功')
        modal.destroyAll()
      } catch {
        message.error('密码重置失败')
      }
    },
    onNegativeClick: () => {
      modal.destroyAll()
    },
  })
}

// 表格列配置 - 渲染函数提取
const renderRoleName = (row: User) => {
  const role = roleList.value.find((r) => r.id === row.role)
  return role ? role.name : row.role
}

const renderStatusTag = (row: User) => {
  const isActive = row.status === 'active'
  return h(
    NTag,
    {
      type: isActive ? 'success' : 'error',
      bordered: false,
    },
    isActive ? '活跃' : '禁用',
  )
}

const renderActions = (row: User) => {
  const actions = []

  // 编辑按钮
  actions.push(
    h(
      NButton,
      {
        secondary: true,
        type: 'primary',
        size: 'small',
        onClick: () => openEditModal(row),
      },
      {
        default: () => '编辑',
        icon: () => h('span', { class: 'iconify ph--pencil' }),
      },
    )
  )

  // 启用/禁用按钮
  actions.push(
    h(
      NButton,
      {
        secondary: true,
        type: row.status === 'active' ? 'warning' : 'success',
        size: 'small',
        onClick: () => toggleUserStatus(row.id, row.status),
      },
      {
        default: () => (row.status === 'active' ? '禁用' : '启用'),
        icon: () =>
          h('span', {
            class: `iconify ${row.status === 'active' ? 'ph--toggle-left' : 'ph--toggle-right'}`,
          }),
      },
    )
  )

  // 重置密码按钮
  actions.push(
    h(
      NButton,
      {
        secondary: true,
        type: 'info',
        size: 'small',
        onClick: () => resetPasswordHandler(row.id),
      },
      {
        default: () => '重置密码',
        icon: () => h('span', { class: 'iconify ph--key' }),
      },
    )
  )

  // 删除按钮
  actions.push(
    h(
      NPopconfirm,
      {
        positiveText: '确定',
        negativeText: '取消',
        onPositiveClick: () => deleteUserHandler(row.id),
      },
      {
        trigger: () => {
          return h(
            NButton,
            {
              secondary: true,
              type: 'error',
              size: 'small',
            },
            {
              default: () => '删除',
              icon: () => h('span', { class: 'iconify ph--trash' }),
            },
          )
        },
        default: () => '确认删除吗？',
      },
    )
  )

  return actions
}

// 动态表格列配置
const getColumns = () => {
  const baseColumns: DataTableColumns<User> = [
    {
      type: 'selection',
      options: ['all', 'none'],
    },
    {
      key: 'username',
      title: '用户名',
      ellipsis: true,
    },
    {
      key: 'email',
      title: '邮箱',
      ellipsis: true,
    },
    {
      key: 'role',
      title: '角色',
      render: renderRoleName,
      ellipsis: true,
    },
    {
      key: 'status',
      title: '状态',
      render: renderStatusTag,
      ellipsis: true,
    },
  ]

  // 大屏幕显示完整列
  if (!isMaxLg.value) {
    baseColumns.push(
      {
        key: 'createdAt',
        title: '创建时间',
        render: (row) => new Date(row.createdAt).toLocaleString(),
        ellipsis: true,
      },
      {
        key: 'updatedAt',
        title: '更新时间',
        render: (row) => new Date(row.updatedAt).toLocaleString(),
        ellipsis: true,
      }
    )
  }

  // 操作列 - 收缩展开效果
  baseColumns.push({
    key: 'actions',
    title: '',
    width: isActionsExpanded.value ? 380 : 0,
    fixed: 'right',
    render: (row) => {
      return h('div', { class: 'flex gap-2 items-center p-2' }, [
        // 只有当展开时才显示操作按钮
        ...(isActionsExpanded.value ? renderActions(row) : []),
      ])
    },
  })

  return baseColumns
}

const columns = computed(() => getColumns())

// 统计数据展示
const statCards = [
  {
    title: '总用户数',
    value: userStats.total,
    type: 'total',
    icon: 'iconify ph--users',
    color: '#3b82f6',
  },
  {
    title: '活跃用户',
    value: userStats.active,
    type: 'active',
    icon: 'iconify ph--check-circle',
    color: '#10b981',
  },
  {
    title: '禁用用户',
    value: userStats.inactive,
    type: 'inactive',
    icon: 'iconify ph--x-circle',
    color: '#ef4444',
  },
]

// 重置搜索表单
function resetSearchForm() {
  searchForm.keyword = null
  searchForm.role = null
  searchForm.status = null
  console.log(searchForm.keyword)
  console.log(searchForm.role)
  console.log(searchForm.status)
  getDataList()
}

// 初始化数据
async function initData() {
  await getRoleList()
  await getDataList()
}

initData()
</script>

<template>
  <ScrollContainer
    wrapper-class="flex flex-col gap-y-4"
    :scrollable="isMaxLg"
  >
    <!-- 统计卡片 -->
    <div class="grid grid-cols-1 gap-4 md:grid-cols-3">
      <NCard
        v-for="card in statCards"
        :key="card.type"
        size="small"
        class="overflow-hidden transition-all duration-300 hover:-translate-y-1 hover:shadow-lg"
        :content-class="'p-4'"
      >
        <div class="flex items-center justify-between">
          <div>
            <h3 class="text-sm font-medium text-neutral-500 dark:text-neutral-400">
              {{ card.title }}
            </h3>
            <div class="mt-1 flex items-baseline gap-2">
              <NNumberAnimation
                :from="0"
                :to="card.value"
                :duration="1500"
                :ease="'easeOutCubic'"
                class="text-3xl font-bold"
                :class="{
                  'text-blue-600 dark:text-blue-400': card.type === 'total',
                  'text-green-600 dark:text-green-400': card.type === 'active',
                  'text-red-600 dark:text-red-400': card.type === 'inactive',
                }"
              />
              <span class="text-sm text-neutral-500 dark:text-neutral-400">人</span>
            </div>
          </div>
          <div
            :class="`flex size-12 items-center justify-center rounded-lg text-white shadow-lg`"
            :style="{
              backgroundColor: card.color,
              boxShadow: `0 4px 15px ${card.color}20`,
            }"
          >
            <span
              :class="card.icon"
              class="text-2xl"
            ></span>
          </div>
        </div>
      </NCard>
    </div>

    <!-- 用户管理表格 -->
    <NCard
      :size="isMaxMd ? 'small' : undefined"
      class="flex-1"
      content-class="flex flex-col"
    >
      <!-- 工具栏 -->
      <div class="mb-4 flex flex-nowrap items-center justify-between gap-x-4 overflow-x-auto toolbar">
        <!-- 搜索表单 -->
        <div class="flex flex-nowrap items-center gap-2 toolbar-left">
          <NInput
            v-model:value="searchForm.keyword"
            clearable
            placeholder="用户名/邮箱"
            @keyup.enter="getDataList"
            style="width: 180px"
          />
          <NSelect
            v-model:value="searchForm.role"
            :options="roleList.map((role) => ({ label: role.name, value: role.id }))"
            placeholder="请选择角色"
            :loading="isLoadingRoles"
            clearable
            @update:value="getDataList"
            style="width: 120px"
          />
          <NSelect
            v-model:value="searchForm.status"
            :options="[
              { label: '活跃', value: 'active' },
              { label: '禁用', value: 'inactive' },
            ]"
            placeholder="请选择状态"
            clearable
            @update:value="getDataList"
            style="width: 80px"
          />
          <NButton
            type="info"
            @click="getDataList"
            :loading="isRequestLoading"
            class="whitespace-nowrap"
          >
            <template #icon>
              <span class="iconify ph--magnifying-glass"></span>
            </template>
            查询
          </NButton>
          <NButton
            type="warning"
            @click="resetSearchForm"
            class="whitespace-nowrap"
          >
            <template #icon>
              <span class="iconify ph--arrow-clockwise"></span>
            </template>
            重置
          </NButton>
        </div>

        <div class="flex flex-nowrap items-center gap-x-4 toolbar-right">
          <NButton
            type="primary"
            @click="openAddModal"
            class="whitespace-nowrap"
          >
            <template #icon>
              <span class="iconify ph--plus-circle"></span>
            </template>
            新增用户
          </NButton>
          <NButton
            type="error"
            :disabled="checkedRowKeys.length === 0"
            @click="batchDeleteHandler"
            class="whitespace-nowrap"
          >
            <template #icon>
              <span class="iconify ph--trash"></span>
            </template>
            批量删除 ({{ checkedRowKeys.length }})
          </NButton>
          <NButton
            type="default"
            size="small"
            @click="isActionsExpanded = !isActionsExpanded"
            class="transition-all duration-300"
            :hidden="dataList.length === 0 && !isRequestLoading"
          >
            <template #icon>
              <span
                class="iconify transition-transform duration-300"
                :class="isActionsExpanded ? 'ph--caret-right' : 'ph--caret-left'"
              />
            </template>
          </NButton>
        </div>
      </div>

      <!-- 数据表格 -->
      <DynamicList
          class="flex-1"
          v-model:checked-row-keys="checkedRowKeys"
          :remote="true"
          :flex-height="!isMaxLg"
          :columns="columns"
          :data="dataList"
          :row-key="(row) => row.id"
          :loading="isRequestLoading"
          :striped="true"
          :estimated-row-count="pagination.itemCount"
          :row-class-name="
            (row, index) =>
              'user-table-row hover:bg-neutral-50 dark:hover:bg-neutral-800 transition-colors duration-150'
          "
          :bordered="false"
          :scroll-x="1800"
        :page="pagination.page"
        :page-size="pagination.pageSize"
        :item-count="pagination.itemCount"
        :show-size-picker="pagination.showSizePicker"
        :show-quick-jumper="pagination.showQuickJumper"
        :page-sizes="pagination.pageSizes"
        @update:page="(page) => { pagination.page = page; getDataList() }"
        @update:page-size="(pageSize) => { pagination.pageSize = pageSize; pagination.page = 1; getDataList() }"
        />
    </NCard>
  </ScrollContainer>
</template>

<style scoped>
/* 操作列样式优化 */
:deep(.n-data-table__td) {
  vertical-align: middle;
}



/* 表格行样式优化 */
.user-table-row {
  cursor: pointer;
}

/* 小屏幕下搜索表单优化 */
@media (max-width: 768px) {
  :deep(.n-input),
  :deep(.n-select) {
    width: 100%;
    min-width: 120px;
  }



  /* 小屏幕下工具栏布局优化 */
  .toolbar {
    flex-direction: column;
    align-items: stretch;
  }

  .toolbar-left,
  .toolbar-right {
    width: 100%;
    justify-content: center;
  }
}


</style>
